package me.lwn.auth.security.web.authentication;

import me.lwn.auth.security.utils.LocalMessageSource;
import me.lwn.auth.security.utils.OAuth2EndpointUtils;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.core.OAuth2ErrorCodes;
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
import org.springframework.security.web.authentication.AuthenticationConverter;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;

import static me.lwn.auth.security.utils.Constants.SPRING_SECURITY_FORM_LOGIN_TYPE_KEY;
import static me.lwn.auth.security.utils.Constants.SPRING_SECURITY_FORM_LOGIN_TYPE_VALUE_PASSWORD;


public class UsernamePasswordAuthenticationConverter implements AuthenticationConverter {

    MessageSourceAccessor message = LocalMessageSource.getAccessor();

    @Override
    public Authentication convert(HttpServletRequest request) {

        // type (REQUIRED)
        String type = request.getParameter(SPRING_SECURITY_FORM_LOGIN_TYPE_KEY);
        if (!SPRING_SECURITY_FORM_LOGIN_TYPE_VALUE_PASSWORD.equals(type)) {
            return null;
        }

        MultiValueMap<String, String> parameters = OAuth2EndpointUtils.getParameters(request);

        // username (REQUIRED)
        String username = parameters.getFirst(OAuth2ParameterNames.USERNAME);
        if (!StringUtils.hasText(username) || parameters.get(OAuth2ParameterNames.USERNAME).size() != 1) {
            OAuth2EndpointUtils.throwError(OAuth2ErrorCodes.INVALID_REQUEST,
                    message.getMessage("UsernamePasswordAuthenticationConverter.usernameRequired"), "");
        }

        // password (REQUIRED)
        String password = parameters.getFirst(OAuth2ParameterNames.PASSWORD);
        if (!StringUtils.hasText(password) || parameters.get(OAuth2ParameterNames.PASSWORD).size() != 1) {
            OAuth2EndpointUtils.throwError(OAuth2ErrorCodes.INVALID_REQUEST,
                    message.getMessage("UsernamePasswordAuthenticationConverter.passwordRequired"), "");
        }

        return new UsernamePasswordAuthenticationToken(username, password);
    }
}
